set encoding=utf-8	" 设置编码
set fileencodings=utf-8	" 设置文件编码
set termencoding=utf-8	" 设置终端编码

" 系统设置
"set clipboard=unnamedplus 	" 让Vim剪切板和系统剪切板共享
set noerrorbells	   	" 出错时，不要发出响声
set novisualbell    " 关闭闪屏
set history=100		" Vim 记住的历史操作次how
set mouse=a 		" 激活鼠标的使用

"" 主题美化
"colorschem zellner	" 主题颜色
autocmd vimenter * ++nested colorscheme gruvbox
set bg=dark			" 强制使用dark模式

"" 显示 & 格式化
syntax on			   " 打开语法高亮
set nu				  " 显示行号
set relativenumber	  " 使用相对行号
set showmatch		" 高亮匹配的括号
set cursorline			" 高亮当前行

"" 缩进 & 制表符
set tabstop=4		" tab 的宽度
set softtabstop=4 	" 删除 tab 的宽度
set expandtab 		" 将 tab 转换为空格
set shiftwidth=4	" 移位操作时的缩进长度
"set autoindent		" 创建新行时使用与上一行同样的缩进
set smartindent		" 智能缩进, 主要用于 C 一类的语言

"" 搜索
set hlsearch		" 高亮搜索内容的所有匹配位置
set incsearch		" 搜索过程中动态显示匹配内容

"" 浏览 & 滚动
set scrolloff=5 	" 使光标放到窗口中间而不是第一行
set ruler	 	" 状态栏显示光标当前位置	

"" 代码折叠
set foldmethod=syntax	" 激活代码折叠(语法高亮)
set foldlevelstart=99 	" 打开文件默认不折叠

"" 代码补全相关
set completeopt=longest,menu	" 智能补全

""" Plug Install
" https://github.com/junegunn/vim-plug
call plug#begin('~/.vim/plugged')
" 启动界面
Plug 'mhinz/vim-startify'
" 图标
Plug 'ryanoasis/vim-devicons'
" 目录树
"Plug 'preservim/nerdtree'
" 状态栏美化
Plug 'vim-airline/vim-airline'
Plug 'vim-airline/vim-airline-themes'
" 主题
Plug 'morhetz/gruvbox'
" 代码补全
Plug 'neoclide/coc.nvim', {'branch': 'release'}
" 代码高亮
Plug 'nvim-treesitter/nvim-treesitter'
Plug 'nvim-treesitter/playground'
" Undo Tree
Plug 'mbbill/undotree'
" 注释
Plug 'preservim/nerdcommenter'
" Plug 'tomtom/tcomment_vim'
"Plug 'tpope/vim-commentary'
" 彩虹括号
Plug 'luochen1990/rainbow'
" 多光标选择
Plug 'mg979/vim-visual-multi', {'branch': 'master'}
" 模糊文件查找
"Plug 'Yggdroot/LeaderF', { 'do': ':LeaderfInstallCExtension' }
Plug 'junegunn/fzf', { 'do': { -> fzf#install() } }
Plug 'junegunn/fzf.vim'
" 文件管理
Plug 'kevinhwang91/rnvimr'
Plug 'airblade/vim-rooter'
"Plug 'pechorin/any-jump.vim'
" 顶部栏
Plug 'mg979/vim-xtabline'
" Flutter
Plug 'dart-lang/dart-vim-plugin'
" 代码补全
Plug 'theniceboy/vim-snippets'
" 代码缩进线
Plug 'Yggdroot/indentLine'
" vue 补全
Plug 'yaegassy/coc-volar', {'do': 'yarn install --frozen-lockfile'}
Plug 'yaegassy/coc-volar-tools', {'do': 'yarn install --frozen-lockfile'}
" Emmet
"Plug 'mattn/emmet-vim'
" 终端
Plug 'akinsho/toggleterm.nvim'
" vim-go
"Plug 'fatih/vim-go', { 'do': ':GoUpdateBinaries' }
"Plug 'fatih/vim-go' , { 'for': ['go', 'vim-plug'], 'tag': '*' }
" 缓冲区
Plug 'famiu/bufdelete.nvim'
call plug#end()


" ==================== toggleterm ====================
" set
autocmd TermEnter term://*toggleterm#*
      \ tnoremap <silent><c-t> <Cmd>exe v:count1 . "ToggleTerm direction=float"<CR>

nnoremap <silent><c-t> <Cmd>exe v:count1 . "ToggleTerm direction=float"<CR>
inoremap <silent><c-t> <Esc><Cmd>exe v:count1 . "ToggleTerm direction=float"<CR>

" ==================== vim-rooter ====================
let g:rooter_patterns = ['__vim_project_root', '.git/']
let g:rooter_silent_chdir = 1

" ==================== any-jump ====================
"nnoremap j :AnyJump<CR>
"let g:any_jump_window_width_ratio  = 0.8
"let g:any_jump_window_height_ratio = 0.9

" ==================== xtabline ====================
let g:xtabline_settings = {}
let g:xtabline_settings.enable_mappings = 0
let g:xtabline_settings.tabline_modes = ['tabs', 'buffers']
let g:xtabline_settings.enable_persistance = 0
let g:xtabline_settings.last_open_first = 1
noremap to :XTabCycleMode<CR>
noremap \p :echo expand('%:p')<CR>

""" Undotree
noremap U :UndotreeToggle<CR>
let g:undotree_DiffAutoOpen = 1
let g:undotree_SetFocusWhenToggle = 1
let g:undotree_ShortIndicators = 1
let g:undotree_WindowLayout = 2
let g:undotree_DiffpanelHeight = 8
let g:undotree_SplitWidth = 24
function g:Undotree_CustomMap()
	nmap <buffer> u <plug>UndotreeNextState
	nmap <buffer> e <plug>UndotreePreviousState
	nmap <buffer> U 5<plug>UndotreeNextState
	nmap <buffer> E 5<plug>UndotreePreviousState
endfunc

""" dart-vim-plugin
let g:dart_style_guide = 2
let g:dart_format_on_save = 1
let g:dartfmt_options = ["-l 100"]

""" fzf
"let g:fzf_preview_window = ['right:50%', 'ctrl-/']
let g:fzf_preview_window = 'right:40%'
let g:fzf_commits_log_options = '--graph --color=always --format="%C(auto)%h%d %s %C(black)%C(bold)%cr"'
" 当前目录下查找文件
" nnoremap <Leader>f :Files <CR>
nnoremap <silent> F :Files <CR>
" 缓冲区查找文件
nnoremap <silent> B :Buffers <CR>

function! s:list_buffers()
  redir => list
  silent ls
  redir END
  return split(list, "\n")
endfunction

function! s:delete_buffers(lines)
  execute 'bwipeout' join(map(a:lines, {_, line -> split(line)[0]}))
endfunction

command! BD call fzf#run(fzf#wrap({
  \ 'source': s:list_buffers(),
  \ 'sink*': { lines -> s:delete_buffers(lines) },
  \ 'options': '--multi --reverse --bind ctrl-a:select-all+accept'
\ }))

" noremap <c-d> :BD<CR>

let g:fzf_layout = { 'window': { 'width': 0.95, 'height': 0.95 } }

""" coc-translator 
nmap tr <Plug>(coc-translator-p)
vnoremap tr <Plug>(coc-translator-p)

""" vim-airline
set laststatus=2  "永远显示状态栏
let g:airline_powerline_fonts = 1  " 支持 powerline 字体
let g:airline#extensions#tabline#enabled = 1 " 显示窗口tab和buffer
let g:airline_theme='murmur'  " murmur配色不错
" let g:airline#extensions#tabline#left_sep = ' '
" let g:airline#extensions#tabline#left_alt_sep = '|'

""" rnvimr
let g:rnvimr_ex_enable = 1
let g:rnvimr_pick_enable = 1  " 读取文件后隐藏
"let g:rnvimr_draw_border = 0 " 禁止浮动窗口的边框
let g:rnvimr_hide_gitignore = 1 " 隐藏 .gitignore 中指定的文件
let g:rnvimr_border_attr = {'fg': 14, 'bg': -1} " 修改边框颜色
" let g:rnvimr_bw_enable = 1
highlight link RnvimrNormal CursorLine
nnoremap <silent> R :RnvimrToggle<CR><C-\><C-n>:RnvimrResize 0<CR>
let g:rnvimr_action = {
			\ '<C-t>': 'NvimEdit tabedit',
			\ '<C-v>': 'NvimEdit vsplit',
			\ '<C-x>': 'NvimEdit split',
			\ 'gw': 'JumpNvimCwd',
			\ 'yw': 'EmitRangerCwd'
			\ }
let g:rnvimr_layout = { 'relative': 'editor',
			\ 'width': &columns,
			\ 'height': &lines,
			\ 'col': 0,
			\ 'row': 0,
			\ 'style': 'minimal' }
let g:rnvimr_presets = [{'width': 0.8, 'height': 0.8}]

""" nvim-treesitter
"if g:nvim_plugins_installation_completed == 1
lua <<EOF
require'nvim-treesitter.configs'.setup {
	ensure_installed = {"typescript", "dart", "java", "vue", "html", "javascript", "yaml", "json", "go"},
	highlight = {
		enable = true,			  -- false will disable the whole extension
	},
}
EOF
"endif

"" nerdcommenter
let g:NERDCreateDefaultMappings = 0  " 关闭默认映射表
let g:NERDSpaceDelims = 1 " 注释前面有1个空格
let g:NERDTrimTrailingWhitespace = 1 " 取消注释去除尾部空格
let g:NERDToggleCheckAllLines = 1 " 不检查其他行是否已经有注释
nmap <Leader>/ <Plug>NERDCommenterToggle
vmap <Leader>/ <Plug>NERDCommenterToggle

""" rainbow
let g:rainbow_active = 1 

""" nerdtree
"将F2设置为开关NERDTree的快捷键
"map <f2> :NERDTreeToggle<cr>
"修改树的显示图标
"let g:NERDTreeDirArrowExpandable = '+'
"let g:NERDTreeDirArrowCollapsible = '-'
"窗口位置
"let g:NERDTreeWinPos='left'
"窗口尺寸
"let g:NERDTreeSize=20
"窗口是否显示行号
"let g:NERDTreeShowLineNumbers=1
"不显示隐藏文件
"let g:NERDTreeHidden=0
 "启动时默认开启NERDTree
"autocmd VimEnter * NERDTree

""" coc.nvim
let g:coc_global_extensions = [
  \ 'coc-json',
  \ 'coc-snippets',
  \ 'coc-pairs',
  \ 'coc-lists',
  \ 'coc-lists',
  \ 'coc-highlight',
  \ 'coc-tsserver',
  \ 'coc-java',
  \ 'coc-prettier',
  \ 'coc-stylelint',
  \ 'coc-html',
  \ 'coc-css',
  \ 'coc-go',
  \ 'coc-explorer',
  \ 'coc-translator',
  \ 'coc-flutter-tools',
  \ 'coc-flutter',
  \ 'coc-lua',
  \ 'coc-vimlsp']

""" coc-explorer
:nmap <space>e <Cmd>CocCommand explorer<CR>

""" LeaderF
"let g:Lf_ShortcutF = "<leader>ff"
"noremap <leader>fl :<C-U><C-R>=printf("Leaderf line %s", "")<CR><CR>
"noremap <leader>fb :<C-U><C-R>=printf("Leaderf buffer %s", "")<CR><CR>
"noremap <leader>fm :<C-U><C-R>=printf("Leaderf mru %s", "")<CR><CR>
"noremap <leader>ft :<C-U><C-R>=printf("Leaderf bufTag %s", "")<CR><CR>

""""" coc.nvim 官网推荐配置
set hidden
set nobackup
"set nowritebackup
"set cmdheight=2
set updatetime=100
set shortmess+=c
set signcolumn=number

"" 使用 tab 进行补全操作
inoremap <silent><expr> <TAB>
	  \ pumvisible() ? coc#_select_confirm() :
	  \ coc#expandableOrJumpable() ? "\<C-r>=coc#rpc#request('doKeymap', ['snippets-expand-jump',''])\<CR>" :
	  \ <SID>check_back_space() ? "\<TAB>" :
	  \ coc#refresh()

function! s:check_back_space() abort
  let col = col('.') - 1
  return !col || getline('.')[col - 1]  =~# '\s'
endfunction

" tab 在 coc_snippet 中进行移动
let g:coc_snippet_next = '<tab>'

" ctrl + / 手动弹出补全
inoremap <silent><expr> <c-/> coc#refresh()

inoremap <silent><expr> <cr> pumvisible() ? coc#_select_confirm()
							  \: "\<C-g>u\<CR>\<c-r>=coc#on_enter()\<CR>"

" 跳到 上/下 一个 报错
nmap <silent> [g <Plug>(coc-diagnostic-prev)
nmap <silent> ]g <Plug>(coc-diagnostic-next)

" 常规编程辅助
nmap <silent> gd <Plug>(coc-definition)
nmap <silent> gy <Plug>(coc-type-definition)
nmap <silent> gi <Plug>(coc-implementation)
nmap <silent> gr <Plug>(coc-references)

" 展示悬浮窗
nnoremap <silent> K :call <SID>show_documentation()<CR>

function! s:show_documentation()
  "有悬浮框则悬浮
  if CocAction('hasProvider', 'hover')
	call CocActionAsync('doHover')
  "没有悬浮框则利用查看帮助
  else
	call feedkeys('K', 'in')
  endif
endfunction

" 让同名变量高亮(not effect)
autocmd CursorHold * silent call CocActionAsync('highlight')

" 重命名
nmap <leader>rn <Plug>(coc-rename)

" 格式化选中的代码
" xmap <leader>f  <Plug>(coc-format-selected)
" nmap <leader>f  <Plug>(coc-format-selected)

" 格式化
augroup mygroup
  autocmd!
  autocmd FileType typescript,json setl formatexpr=CocAction('formatSelected')
  autocmd User CocJumpPlaceholder call CocActionAsync('showSignatureHelp')
augroup end

" 给选中代码一些操作
xmap <leader>a <Plug>(coc-codeaction-selected)
nmap <leader>aw <Plug>(coc-codeaction-selected)w
" 当前文件的一些代码操作
nmap <leader>ac  <Plug>(coc-codeaction)
" 快速修复
nmap <leader>qf  <Plug>(coc-fix-current)

" Run the Code Lens action on the current line.
nmap <leader>cl  <Plug>(coc-codelens-action)

" Map function and class text objects
" NOTE: Requires 'textDocument.documentSymbol' support from the language server.
xmap if <Plug>(coc-funcobj-i)
omap if <Plug>(coc-funcobj-i)
xmap af <Plug>(coc-funcobj-a)
omap af <Plug>(coc-funcobj-a)
xmap ic <Plug>(coc-classobj-i)
omap ic <Plug>(coc-classobj-i)
xmap ac <Plug>(coc-classobj-a)
omap ac <Plug>(coc-classobj-a)

" <C-f> 和 <C-b> 来对悬浮框的内容进行滚动
if has('nvim-0.4.0') || has('patch-8.2.0750')
  nnoremap <silent><nowait><expr> <C-f> coc#float#has_scroll() ? coc#float#scroll(1) : "\<C-f>"
  nnoremap <silent><nowait><expr> <C-b> coc#float#has_scroll() ? coc#float#scroll(0) : "\<C-b>"
  inoremap <silent><nowait><expr> <C-f> coc#float#has_scroll() ? "\<c-r>=coc#float#scroll(1)\<cr>" : "\<Right>"
  inoremap <silent><nowait><expr> <C-b> coc#float#has_scroll() ? "\<c-r>=coc#float#scroll(0)\<cr>" : "\<Left>"
  vnoremap <silent><nowait><expr> <C-f> coc#float#has_scroll() ? coc#float#scroll(1) : "\<C-f>"
  vnoremap <silent><nowait><expr> <C-b> coc#float#has_scroll() ? coc#float#scroll(0) : "\<C-b>"
endif

" 使用 ctrl + s 来选中一段代码块
nmap <silent> <C-s> <Plug>(coc-range-select)
xmap <silent> <C-s> <Plug>(coc-range-select)

" `:Format` 格式化当前缓冲区(目前设置保存时自动格式化)
"command! -nargs=0 Format :call CocActionAsync('format')

" Add `:Fold` command to fold current buffer.
command! -nargs=? Fold :call CocAction('fold', <f-args>)

" `:OR` 当前文件自动导包
command! -nargs=0 OR :call CocActionAsync('runCommand', 'editor.action.organizeImport')

" Add (Neo)Vim's native statusline support.
" NOTE: Please see `:h coc-status` for integrations with external plugins that
" provide custom statusline: lightline.vim, vim-airline.
"set statusline^=%{coc#status()}%{get(b:,'coc_current_function','')}

" Mappings for CoCList
" Show all diagnostics.
" nnoremap <silent><nowait> <space>a  :<C-u>CocList diagnostics<cr>
" Manage extensions.
"nnoremap <silent><nowait> <space>e  :<C-u>CocList extensions<cr>
" Show commands.
nnoremap <silent><nowait> <space>cc  :<C-u>CocList commands<cr>
" Find symbol of current document.
"nnoremap <silent><nowait> <space>o  :<C-u>CocList outline<cr>
" Search workspace symbols.
"nnoremap <silent><nowait> <space>s  :<C-u>CocList -I symbols<cr>
" Do default action for next item.
"nnoremap <silent><nowait> <space>j  :<C-u>CocNext<CR>
" Do default action for previous item.
"nnoremap <silent><nowait> <space>k  :<C-u>CocPrev<CR>
" Resume latest coc list.
"nnoremap <silent><nowait> <space>p  :<C-u>CocListResume<CR>

let g:coc_disable_transparent_cursor = 1

""""" person habit
" <LEADER> 就是一个前缀键, 可以自由设定
" <LEADER> 设置为空格
let g:mapleader = " "

" 复制到系统剪切板
vnoremap Y "+y
" 粘贴系统剪切板的内容
nnoremap <C-v> "+p
" 保存
nnoremap <C-s> :w<CR>
" 利用 bufdelete 关闭缓冲区
nnoremap Q :Bdelete<CR>

" 取消搜索的高亮
noremap <LEADER><CR> :nohlsearch<CR>
" 复制所有
nnoremap <C-a> ggVG

" Open the vimrc file anytime
nnoremap <LEADER>cfg :e $HOME/.config/nvim/init.vim<CR>

" Space to Tab
" nnoremap <LEADER>tt :%s/	/\t/g
" vnoremap <LEADER>tt :s/	/\t/g

"" window manage
" 移动到指定方向的屏幕
noremap <LEADER>w <C-w>w
noremap <LEADER>h <C-w>h
noremap <LEADER>j <C-w>j
noremap <LEADER>k <C-w>k
noremap <LEADER>l <C-w>l
" 方向键调整窗口大小
noremap <up> :res +5<CR>
noremap <down> :res -5<CR>
noremap <left> :vertical resize-5<CR>
noremap <right> :vertical resize+5<CR>
" 分裂窗口
noremap <LEADER>sk :set nosplitbelow<CR>:split<CR>:set splitbelow<CR>
noremap <LEADER>sj :set splitbelow<CR>:split<CR>
noremap <LEADER>sh :set nosplitright<CR>:vsplit<CR>:set splitright<CR>
noremap <LEADER>sl :set splitright<CR>:vsplit<CR>
" 关闭当前窗口
noremap <LEADER>qq <C-w>j:q<CR>

"" tab manage
" 创建新标签
noremap tn :tabe<CR>
noremap tN :tab split<CR>
" 移至左/右标签
noremap th :-tabnext<CR>
noremap tl :+tabnext<CR>
" 移动当前标签页
noremap tmh :-tabmove<CR>
noremap tml :+tabmove<CR>

""""" compile & run
noremap <Leader>rr :call CompileRunGcc()<CR>
func! CompileRunGcc()
	exec "w"
	if &filetype == 'lua'
		set splitbelow
		:sp
		:res -5
		term lua %
	elseif &filetype == 'java'
		set splitbelow
		:sp
		:res -5
		term javac % && time java %<
	elseif &filetype == 'sh'
		:!time bash %
	elseif &filetype == 'python'
		set splitbelow
		:sp
		:term python3 %
	elseif &filetype == 'html'
		silent! exec "!".g:mkdp_browser." % &"
	elseif &filetype == 'markdown'
		exec "InstantMarkdownPreview"
	elseif &filetype == 'dart'
		exec "CocCommand flutter.run -d ".g:flutter_default_device." ".g:flutter_run_args
		silent! exec "CocCommand flutter.dev.openDevLog"
	elseif &filetype == 'javascript'
		set splitbelow
		:sp
		:term export DEBUG="INFO,ERROR,WARNING"; node --trace-warnings .
	elseif &filetype == 'go'
		set splitbelow
		:sp
        :term go run %
        ":term go run .
	endif
endfunc

""""" lua 文件引用
" keybindings 快捷键映射
lua require('keybindings')
